const RESSTATE = require("./states/resstates");
const tools = require("./pub/tools");
class Animate{
    constructor(){
        this._EffectAudioIds = {};
    }

    do( meth ){
        let args = Array.prototype.slice.call(arguments);
        let newArgs = args.splice(1);
        let me = this;
        if( newArgs[newArgs.length-1] instanceof cc.AudioClip ){
            tools.playEffect(newArgs[newArgs.length-1]);
            newArgs.splice(newArgs.length-1);
        }
        let p = new Promise( (resolve, reject)=>{
            let arr= [resolve , reject];
            if( typeof meth == 'function'){
                meth.apply( args.splice(1,1) , arr.concat(args.splice(2)) )
            }else if( me[meth] ){
                me[meth].apply( this , arr.concat(newArgs) )
            }else{
                resolve( RESSTATE.NOTHING );
                reject('cant find meth:' + meth);
            }
        });
        return p;
    }

    run( meth , node , timmer , cb , err){
        if( me[meth] ){
            me[meth]( 
                (()=>{
                    cb && cb();
                }), 
                ()=>{
                    err && err();
                } , 
                node, timmer );
        }else{
            cb && cb();
        }
        return this;
    }

    playPop( res , rej , node , timmer , p ){
        if( !node || !cc ){
            res()
        };
        let max = 1 + (p?p.u : .5 ),
            min = 1 + (p?p.d : -0.1 ),
            sc = p && p.sc ? p.sc : 1;
        node.runAction(
            cc.sequence(
                cc.scaleTo( .06 , max),
                cc.scaleTo( .1 , min),
                cc.scaleTo( .06 , sc ),
                cc.scaleTo( timmer ? timmer : 0 , sc ),
                cc.callFunc(()=>{
                    res && res( RESSTATE.SUCCESS )
                })
            )
        );

        return this;
    }

    playUnPop( res , rej , node , timmer , p){
        if( !node || !cc ){
            res()
        };
        let max = 1 + (p && p.u?p.u : .5 ),
            min = 1 + (p && p.d?p.d : -0.1 ),
            sc = p && p.sc ? p.sc : 1;
        node.runAction(
            cc.sequence(
                cc.scaleTo( .06 , min ),
                cc.scaleTo( .1 , max ),
                cc.scaleTo( .06 , sc ),
                cc.scaleTo( timmer ? timmer : 0 , sc ),
                cc.callFunc(()=>{
                    res && res( RESSTATE.SUCCESS )
                })
            )
        );

        return this;
    }

    ring( res , rej , node , timmer){
        if(!node || !cc ) res();
        node.runAction(
            cc.spawn(
                cc.sequence(
                    cc.rotateTo( 40 , -180),
                    cc.rotateTo( 40 , -360 ),
                    cc.rotateTo( 0 , 0 )
                ).repeatForever(),
                
                cc.sequence(
                    cc.scaleTo( timmer ? timmer : 0 , 1 ),
                    cc.callFunc(()=>{
                        res( RESSTATE.SUCCESS );
                    })
                )
            )
        );

        return this;
    }

    showNode( res , rej , node , type , v , isshow , timmer ){
        type = type || "left";
        isshow = !!isshow;
        let f = 0 ;
        if( type == "left" || type == "right" ){
            if(isshow){
                node.x = type == 'left' ? -800 : 800;
            }else{
                v = type == 'left' ? -800 : 800;
            }
        }else{
            if(isshow){
                node.y = type == 'up' ? 1000 : -1000;
            }else{
                v = type == 'up' ? 1000 : -1000;
            }
            f = 1;
        }
        
        node.runAction(
            cc.sequence(
                !f ? cc.moveTo(.2 , cc.v2(v , node.y ))
                   : cc.moveTo(.2 , cc.v2( node.x , v)) ,
                cc.callFunc(()=>{
                    me.do('playPop' , node , timmer ).then(()=>{
                        res && res( RESSTATE.SUCCESS );
                    })
                })
            )
        );
    }

    cameraSharkeIn( res , rej , camera , data , timer ){
        timer = timer || [.5 , .3];
        data = data || [1.5 , 1];
        let animte = cc.tween(camera);
        for( let i in data ){
            animte.to(  timer[i] ? timer[i] : .5  , { zoomRatio : data[i] ? data[i] : 1.5 } )
        }
        animte.call(()=>{
            res();
        })
        .start();
    }

    //元素滑入右边视界外
    hideRight( res , rej , node , timmer){
        node.runAction(
            cc.sequence(
                cc.spawn(
                    cc.moveBy(.2 , cc.v2(-100, 0)),
                    cc.scaleTo(.2 , .8 , 1)
                ),
                cc.spawn(
                    cc.scaleTo(.03 , 1 , 1),
                    cc.moveTo(.1 , cc.v2(1000, node.y)),
                ),
                cc.scaleTo( timmer ? timmer : 0 , 1 ),
                cc.callFunc(()=>{
                    node.active = false;
                    res( RESSTATE.SUCCESS );
                })
            )
        );
    }

    flyNodeToNodeBezier( res , rej , node , toNode, bezierParam , timmer ){
        let toPos = toNode.convertToWorldSpaceAR ? 
                    node.parent.convertToNodeSpaceAR(toNode.convertToWorldSpaceAR( cc.v2(0,0) )) :
                    cc.v2(toNode.x , toNode.y);
        node.runAction(
            cc.sequence(
                this._create(
                    timmer ? timmer : 1.5,
                    node.getPosition(), 
                    toPos,
                    bezierParam && bezierParam.height ? bezierParam.height : 600,
                    bezierParam && bezierParam.angle ? bezierParam.angle : 120
                ),

                cc.callFunc(()=>{
                    res && res();
                })
            )
        )
    }

    //动画使node飞跃到指定node处
    flyNodeToNode(  res , rej , node , toNode, timmer ){
        let toPos = toNode.convertToWorldSpaceAR( cc.v2(0,0) );
        toPos = node.parent.convertToNodeSpaceAR(toPos);

        me.do('playPop' , node , .1)
        .then(()=>{
            node.runAction(
                cc.sequence(
                    cc.moveTo(.2 , toPos ),
                    cc.moveBy(.1, cc.v2(0,50) ),
                    cc.scaleTo( timmer ? timmer : 0 , 1 ),
                    cc.spawn(
                        cc.fadeOut(.1 ),
                        cc.callFunc(()=>{
                            res( RESSTATE.SUCCESS );
                        })
                    )
                )
            )
        })
    }
    //动画使node飞跃到指定node处
    flyNodeToNode_plus(  res , rej , node , toNode, long , offset , timmer ){
        long = tools.selectValue(long , .2);
        offset = offset || {x:0,y:0}
        // if(!node || !node.parent || !toNode || !toNode.convertToWorldSpaceAR){
        //     if( node && !node.parent){

        //     }else{
        //         res();
        //         return;
        //     }
        // }
        let toPos , fail = false;
        try{
            toPos = toNode.convertToWorldSpaceAR( cc.v2(0,0) );
            toPos = node.parent.convertToNodeSpaceAR(toPos);
        }catch(e){
            res && res( RESSTATE.FAIL );
            fail = true;
        }
        if(fail) return;
        
        if(long==0){
            node.setPosition( cc.v2(toPos.x+offset.x , toPos.y+offset.y) );
            timmer = tools.selectValue(timmer , 0);
            cc.tween(node)
            .to( 0 , {x : toPos.x+offset.x , y:toPos.y+offset.y})
            .delay(timmer)
            .call(()=>{
                res( RESSTATE.SUCCESS );
            })
        }else
            node.runAction(
                cc.sequence(
                    cc.moveTo(long?long:.2 , cc.v2(toPos.x+offset.x , toPos.y+offset.y) ),
                    cc.scaleTo( timmer ? timmer : 0 , node.getScale() ),
                    //cc.spawn(
                        cc.callFunc(()=>{
                            res( RESSTATE.SUCCESS );
                        })
                    //)
                )
            )
    }

    //摇动一下
    yaotou( res , rej , node , sound ){
        if(!node){
            res();
            return;
        }
        
        this.__yaotouing_arr =  this.__yaotouing_arr ||[];

        if( this.__yaotouing_arr.indexOf(node._id) < 0 ){
            this.__yaotouing_arr.push(node._id);
            let pos = node.getPosition();
            if(sound) tools.playEffect( sound );

            cc.tween( node )
            .to(.08 , { x:pos.x + 20 })
            .to(.08 , { x:pos.x - 20 })
            .to(.06 , { x:pos.x + 15 })
            .to(.05 , { x:pos.x - 12 })
            .to(.03 , { x:pos.x + 8 })
            .to(.03 , { x:pos.x - 8 })
            .to(.01 , { x:pos.x})
            .call(()=>{
                this.__yaotouing_arr.splice(  this.__yaotouing_arr.indexOf(node._id) ,1 );
                res( RESSTATE.SUCCESS );
            })
            .start();
        }
    }

    playShake(  res , rej , node , ret, sound  ){
        if(!node){
            res();
            return;
        }
        ret = ret || 1;
        this.__shakeing_arr =  this.__shakeing_arr ||[];

        if( this.__shakeing_arr.indexOf(node._id) < 0 ){
            this.__shakeing_arr.push(node._id);
            let pos = node.getPosition();
            if(sound) tools.playEffect( sound );
            let vs = [ [.06,6], [.05,-9], [.03,8], [.03 ,-3], [.01 ,1] ];
            let action = cc.tween( node );
            for(let i in vs){
                action.by( vs[i][0] , {y: vs[i][1] * ret });
            }
            action
            .call(()=>{
                node.setPosition( pos );
                this.__shakeing_arr.splice(  this.__shakeing_arr.indexOf(node._id) ,1 );
                res( RESSTATE.SUCCESS );
            })
            .start();
        }
    }

    // 抛物线创建
    _create( t, startPoint, endPoint, height, angle ) {
        // 把角度转换为弧度
        let radian = angle * 3.14159 / 180;
        // 第一个控制点为抛物线左半弧的中点
        let q1x = startPoint.x + (endPoint.x - startPoint.x) / 4;
        let q1 = cc.v2(q1x, height + startPoint.y + Math.cos(radian) * q1x);
        // 第二个控制点为整个抛物线的中点
        let q2x = startPoint.x + (endPoint.x - startPoint.x) / 2;
        let q2 = cc.v2(q2x, height + startPoint.y + Math.cos(radian) * q2x);
        // 曲线配置
        return cc.bezierTo(t, [q1, q2, endPoint]).easing(cc.easeInOut(0.8));
    }
}


module.exports = Animate;